package com.fdb.efp.nls.service.impl;

import com.fdb.basic.framework.core.base.FrameworkService;
import com.fdb.basic.framework.core.constant.MonAlrmLvlEnums.MonAlrmLvlEnum;
import com.fdb.basic.framework.core.constant.StdZbHandleEnums;
import com.fdb.basic.framework.core.util.DateTool;
import com.fdb.basic.framework.core.util.DateUtility;
import com.fdb.basic.framework.core.util.UUIDUtil;
import com.fdb.efp.nls.service.facade.BatInstBatchMonService;
import com.fdb.efp.nls.service.vo.LogErrorInfoVO;
import com.fdb.efp.nls.service.facade.LogErrorInfoService;
import com.fdb.efp.esb.service.bo.req.hlw.ReqAlarmJudgementBean;
import com.fdb.efp.esb.service.bo.resp.hlw.RespAlarmJudgementBean;
import com.fdb.efp.esb.service.facade.hlw.AlarmJudgementService;
import com.fdb.efp.nls.service.facade.AccoutErroTempService;
import com.fdb.efp.nls.service.facade.BatInstBatchService;
import com.fdb.efp.nls.service.vo.AccoutErroTempVO;
import com.fdb.efp.nls.service.vo.BatInstBatchVO;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.net.InetAddress;
import java.util.List;
import java.util.Objects;

/**
 * 
 * 监控批次实例信息是否完成
 * 
 * @author ludayong
 * @since 2019年4月12日 上午11:43:34
 * @version 1.0
 */
@Service("batInstBatchMonService")
public class BatInstBatchMonServiceImpl implements BatInstBatchMonService, FrameworkService {

	private static Logger logger = LoggerFactory.getLogger(BatInstBatchMonServiceImpl.class);

	//批次运行状态出错（"1"）
	private static String BATCH_STATE_ERROR = "1";

	// 批次实例信息
	@Autowired
	@Qualifier("batInstBatchService")
	private BatInstBatchService batInstBatchService;

	// 记录异常信息
	@Autowired
	@Qualifier("accoutErroTempService")
	private AccoutErroTempService accoutErroTempService;

	// 告警服务
	@Autowired
	@Qualifier("alarmJudgementService")
	private AlarmJudgementService alarmJudgementService;


	/**
	 * 
	 * 监控批次实例信息是否完成 <br>
	 * 0.1:ludayong:2019年7月15日 下午5:22:02:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年7月15日 下午5:22:02
	 * @date 2019年7月15日 下午5:22:02
	 * @version 0.1
	 */
	@Override
	public boolean batInstBatchMonSingle(String batchId, String curDate) throws Exception {
		boolean result = false;
		logger.info("监控批次实例信息是否完成：批次标识[" + batchId + "]，批次日期[" + curDate + "]开始");
		try {
			BatInstBatchVO batInstBatchVo = new BatInstBatchVO();
			// 批次标识
			batInstBatchVo.setBatchId(batchId);
			// 批次日期
			batInstBatchVo.setBatchDate(curDate);
			// 状态 9 完成
			batInstBatchVo.setBatchState("9");
			// 通过批次标识和批次日期查询、状态查询批次实例信息
			BatInstBatchVO queryBatInstBatchVO = batInstBatchService.queryByCondition(batInstBatchVo);
			// 批次实例信息不为空
			if (Objects.nonNull(queryBatInstBatchVO)) {
				result = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			String errorMsg = "监控批次实例信息是否完成出现异常";
			String remark = "监控批次实例信息是否完成出现异常，异常信息：" + e.getMessage();
			addErrorInfo("bat_inst_batch", MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
		}
		logger.info("监控批次实例信息是否完成：" + batchId + "开始，处理结果[" + result + "]");
		return result;
	}

	/**
	 * 
	 * 监控批次实例信息是否完成 <br>
	 * 0.1:ludayong:2019年7月15日 下午5:22:02:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年7月15日 下午5:22:02
	 * @date 2019年7月15日 下午5:22:02
	 * @version 0.1
	 */
	@Override
	public boolean batInstBatchMonSingle(String batchId, String curDate, String num) throws Exception {
		boolean result = false;
		logger.info("监控批次实例信息是否完成：批次标识[" + batchId + "]，批次日期[" + curDate + "]开始");
		try {
			String newDate = DateUtility.ADD_DAY(curDate, Integer.parseInt(num));
			BatInstBatchVO batInstBatchVo = new BatInstBatchVO();
			// 批次标识
			batInstBatchVo.setBatchId(batchId);
			// 批次日期
			batInstBatchVo.setBatchDate(newDate);
			// 状态 9 完成
			batInstBatchVo.setBatchState("9");
			// 通过批次标识和批次日期查询、状态查询批次实例信息
			BatInstBatchVO queryBatInstBatchVO = batInstBatchService.queryByCondition(batInstBatchVo);
			// 批次实例信息不为空
			if (Objects.nonNull(queryBatInstBatchVO)) {
				result = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			String errorMsg = "监控批次实例信息是否完成出现异常";
			String remark = "监控批次实例信息是否完成出现异常，异常信息：" + e.getMessage();
			addErrorInfo("bat_inst_batch", MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
		}
		logger.info("监控批次实例信息是否完成：" + batchId + "开始，处理结果[" + result + "]");
		return result;
	}


	@Autowired
	@Qualifier("logErrorInfoService")
	private LogErrorInfoService logErrorInfoService;

	/**
	 *
	 * 监控批次运行失败记录 <br>
	 * 0.1:wanglaisheng:2020年11月25日 新增 <br>
	 *
	 * @author wanglaisheng
	 * @since 2020年11月25日
	 * @date 2020年11月25日
	 * @version 0.1
	 */
	@Override
	public boolean getErrorRunningBatInst() {
		boolean result = false;
		try {
			logger.info("监控批次任务运行出错情况开始");
			BatInstBatchVO queryCondition = new BatInstBatchVO();
			String currentDate = DateTool.getCurrentDate();
			queryCondition.setBatchDate(currentDate);
			//批次运行状态出错
			queryCondition.setBatchState(BATCH_STATE_ERROR);
			List<BatInstBatchVO> lstBatInstBatch = batInstBatchService.queryListByCondition(queryCondition);
			if (CollectionUtils.isNotEmpty(lstBatInstBatch)) {
				logger.info("监控到运行出错的批次实例有"+lstBatInstBatch.size()+"条");
				for (BatInstBatchVO batInstBatch : lstBatInstBatch) {
					String batchId = batInstBatch.getBatchId();
					String batchDate = batInstBatch.getBatchDate();
					String applySeq = batchDate+"_"+batchId;
					LogErrorInfoVO queryLogErrorInfo = new LogErrorInfoVO();
					queryLogErrorInfo.setApplySeq(applySeq);
					LogErrorInfoVO isRecorded = logErrorInfoService.queryByApplySeq(queryLogErrorInfo);
					String msg = "批次运行出错：批次日期：" + batchDate + "，批次实例ID【" + batchId + "】，批次实例名称：" +
							batInstBatch.getBatchName();
					if (Objects.isNull(isRecorded)) {
						logger.info(msg);
						//发送告警
						ReqAlarmJudgementBean reqAlarmJudgementBean = new ReqAlarmJudgementBean();
						reqAlarmJudgementBean.setMonObjNm("网贷跑批");
						reqAlarmJudgementBean.setMonObjSpfTpVal("网贷跑批");
						try {
							// 应用地址
							reqAlarmJudgementBean.setMonObjLctr(InetAddress.getLocalHost().getHostAddress());
						} catch (Exception e) {
							reqAlarmJudgementBean.setMonObjLctr("efp_daybat");
						}
						reqAlarmJudgementBean.setAlrmInf(msg);
						reqAlarmJudgementBean.setAlrmTmstmp(DateUtility.getCurrAppDateTimeString());
						reqAlarmJudgementBean.setMonAlrmLvl(MonAlrmLvlEnum.SERIOUS.getEnname());
						RespAlarmJudgementBean imageFileRespBean = alarmJudgementService.alarmJudgement(reqAlarmJudgementBean);
						logger.info("调用告警返回码：【" + imageFileRespBean.getRetCd() + "】，返回信息：【" + imageFileRespBean.getRetMsg() + "】");
						//记录到日志表
						LogErrorInfoVO logErrorInfoVO = new LogErrorInfoVO();
						logErrorInfoVO.setErrorMsg(msg);
						logErrorInfoVO.setApplySeq(applySeq);
						//日志错误信息状态-2处理
						logErrorInfoVO.setState(StdZbHandleEnums.StdZbHandleEnum.SUCCESS.getEnname());
						//日志错误信息状态-3严重
						logErrorInfoVO.setErrorType(MonAlrmLvlEnum.SERIOUS.getEnname());
						logErrorInfoVO.setSerno(UUIDUtil.getUUID());
						String currentDateTime = DateTool.getCurrentDateTime();
						logErrorInfoVO.setCreateTime(currentDateTime);
						logErrorInfoVO.setLastModifyTime(currentDateTime);
						logErrorInfoService.insertLogErrorInfo(logErrorInfoVO);
					}else {
						logger.info("已发送过告警，不再重复发送："+msg);
					}
				}
			}else {
				logger.info("未发现运行出错的批次");
			}
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("监控批次任务运行情况异常！" + e.getMessage());
		}
		logger.info("监控批次任务运行情况完成");
		return result;
	}

	/**
	 * 
	 * 记录异常信息 <br>
	 * 0.1:ludayong:2019年5月7日 上午11:31:23:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 上午11:31:23
	 * @date 2019年5月7日 上午11:31:23
	 * @version 0.1
	 */
	private void addErrorInfo(String tableName, String errorType, String errorMsg, String remark) {
		AccoutErroTempVO accoutErroTempVO = new AccoutErroTempVO();
		// 表名
		accoutErroTempVO.setTableName(tableName);
		// 错误级别
		accoutErroTempVO.setErroType(errorType);
		// 错误信息
		accoutErroTempVO.setErroMsg(errorMsg);
		// 备注
		accoutErroTempVO.setRemark(remark);
		// 创建时间
		accoutErroTempVO.setCreateData(DateTool.getCurrentDateTime());
		// 修改时间
		accoutErroTempVO.setLastModifyTime(DateTool.getCurrentDateTime());
		// 记录异常信息
		accoutErroTempService.insert(accoutErroTempVO);
	}
}
